/*
 * Dcm_UDS0x2A.c
 *
 *  Created on: 2018-9-26
 *      Author: tao.yu
 */

#include "UDS.h"


/****************************************************************
         UDS:ReadDataByPeriodicIdentifier  (2A hex) service
 ***************************************************************/
#if(STD_ON == DCM_UDS_SERVICE0X2A_ENABLED)


#define  DCM_START_SEC_VAR_NOINIT_UNSPECIFIED
#include "Dcm_MemMap.h"
VAR(SchedulerQueueTypes, DCM_VAR_NOINIT) SchedulerQueue[DCM_DSP_MAX_PERIODIC_DID_SCHEDULER];
#define  DCM_STOP_SEC_VAR_NOINIT_UNSPECIFIED
#include "Dcm_MemMap.h"

typedef struct
{
    uint16 Did;
    uint16 Length;
    boolean DDDid;
}DidRxQueueTypes;

#if(STD_ON == DCM_UDS_SERVICE0X2C_ENABLED)
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x2A_DDDidCheck(
        Dcm_OpStatusType OpStatus,
        uint16 receiveDid,
        P2VAR(uint8, AUTOMATIC, DCM_VAR_NOINIT)pRangeDidCfgIndex,
        P2VAR(uint16, AUTOMATIC, DCM_VAR_NOINIT)pDidCfgIndex,
        P2VAR(boolean, AUTOMATIC, DCM_VAR_NOINIT)pRangeDidFlag)
{
    Dcm_DidSupportedType    DidSupported;
    uint16     Index;
    uint8     Idx;
    boolean   Flag = FALSE;
    boolean   Flagx = FALSE;
    Std_ReturnType  ret = E_NOT_OK;
    uint8 iloop;

    *pRangeDidFlag = FALSE;
    /*SWS_Dcm_00438*/
    /*first check whether the receiveDid is single did*/
    for (Index = 0;(Index < Dcm_DspCfg.DcmDspDidNum) && (FALSE == Flag); Index++)
    {
        /*single did check*/
        if ((receiveDid == Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidId)
        &&(TRUE == Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidUsed))
        {
            if ((receiveDid > 0xF200u) && (receiveDid < 0xF3FFu)
               && (Dcm_DspCfg.pDcmDspDidInfo[Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidInfoIndex].
                       DcmDspDidDynamicallyDefined == TRUE)
               && (Dcm_DspCfg.pDcmDspDidInfo[Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidInfoIndex].
                       DcmDspDDDIDMaxElements > 0u))
            {
               for (iloop = 0; (iloop < DCM_DSP_DDDID_MAX_NUMBER) && (Flag == FALSE); iloop++)
               {
                   if (Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidId == Dcm_DDDid[iloop].DDDid)
                   {
                       Flag = TRUE;
                       (*pDidCfgIndex) = Index;
                       ret = E_OK;
                   }
               }
            }
            else
            {
                Flag = TRUE;
                (*pDidCfgIndex) = Index;
                ret = E_OK;
            }
        }
    }
    /*if the receiveDid is not single did,the check whether the receiveDid is range did*/
    if (FALSE == Flag)
    {
        /*range did check*/
        if ((receiveDid < 0xF200u) || (receiveDid > 0xF3FFu))
        {
            /*range did can not be DDDid*/
            for (Idx = 0; (Idx < Dcm_DspCfg.DcmDspDidRangeNum) && (FALSE == Flagx); Idx++)
            {
                /*this range not have gaps*/
                if ((receiveDid >= Dcm_DspCfg.pDcmDspDidRange[Idx].DcmDspDidRangeIdentifierLowerLimit)
                   &&(receiveDid <= Dcm_DspCfg.pDcmDspDidRange[Idx].DcmDspDidRangeIdentifierUpperLimit))
                {
                    if (TRUE == Dcm_DspCfg.pDcmDspDidRange[Idx].DcmDspDidRangeHasGaps)
                    {
                        if (FALSE == Dcm_DspCfg.pDcmDspDidRange[Idx].DcmDspDidRangeUsePort)
                        {
                            if (Dcm_DspCfg.pDcmDspDidRange[Idx].DcmDspDidRangeIsDidAvailableFnc
                                    != NULL_PTR)
                            {
                                ret = Dcm_DspCfg.pDcmDspDidRange[Idx].DcmDspDidRangeIsDidAvailableFnc(
                                        receiveDid,
                                        OpStatus,
                                        &DidSupported);
                                if (ret == E_OK)
                                {
                                    if (DCM_DID_SUPPORTED == DidSupported)
                                    {
                                        *pRangeDidCfgIndex = Idx;
                                        *pRangeDidFlag = TRUE;
                                        Flagx = TRUE;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        *pRangeDidCfgIndex = Idx;
                        *pRangeDidFlag = TRUE;
                        Flagx = TRUE;
                    }
                }
            }
        }

        if (FALSE == Flagx)
        {
            ret = E_NOT_OK;
        }
        else
        {
            (*pDidCfgIndex) = Index;
            ret = E_OK;
        }
    }

    return(ret);
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif
#endif

#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x2A_Did_Read_Data(
                        uint16     RecDid,
                        P2VAR(uint8, AUTOMATIC, AUTOMATIC)Data)
{
    uint16 DidSignalPos = 0;
    uint8 DidSignalIndex;
    uint8 DidSignalNum;
    P2CONST(Dcm_DspDataType,TYPEDEF,DCM_CONST) pDspDidData;
    Std_ReturnType ret = E_NOT_OK;
    uint16 Size;
    uint8     Index;
    boolean   Flag = FALSE;
    uint16 DidCfgIndex = 0;
    Dcm_NegativeResponseCodeType ErrorCode;

    /*SWS_Dcm_00438*/
    for (Index = 0;(Index < Dcm_DspCfg.DcmDspDidNum) && (FALSE == Flag); Index++)
    {
        /*single did check*/
        if ((RecDid == Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidId)
        &&(TRUE == Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidUsed))
        {
            Flag = TRUE;
            DidCfgIndex = Index;
            ret = E_OK;
        }
    }

    if (ret == E_OK)
    {
        DidSignalNum = Dcm_DspCfg.pDcmDspDid[DidCfgIndex].DcmDspDidSignalNum;
        for (DidSignalIndex = 0; DidSignalIndex < DidSignalNum; DidSignalIndex ++)
        {
            pDspDidData = Dcm_DspCfg.pDcmDspDid[DidCfgIndex].
                    pDcmDspDidSignal[DidSignalIndex].pDcmDspDidData;
            Size = 0;
            if (DCM_UINT8_DYN == pDspDidData->DcmDspDataType)
            {
                /*DidDataSize is dynamic*/
                if (NULL_PTR == pDspDidData->DcmDspDataReadDataLengthFnc)
                {
                    ret = E_NOT_OK;
                }
                else if((USE_DATA_SYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                        || (USE_DATA_SYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort))
                {
                    ret = pDspDidData->DcmDspDataReadDataLengthFnc(DCM_INVALID_UINT8, &Size);
                }
                else if((USE_DATA_ASYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                        || (USE_DATA_ASYNCH_FNC_ERROR == pDspDidData->DcmDspDataUsePort)
                        || (USE_DATA_ASYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort)
                        || (USE_DATA_ASYNCH_CLIENT_SERVER_ERROR == pDspDidData->DcmDspDataUsePort))
                {
                    ret = pDspDidData->DcmDspDataReadDataLengthFnc(DCM_INITIAL, &Size);
                }
                else
                {}
            }
            else
            {
                /*DidDataSize is fixed*/
                Size = ((pDspDidData->DcmDspDataSize + 7u) >> 3u);
            }
            DidSignalPos +=((Dcm_DspCfg.pDcmDspDid[DidCfgIndex].
                    pDcmDspDidSignal[DidSignalIndex].DcmDspDidDataPos + 7u) >> 3u);
            if (NULL_PTR == pDspDidData->DcmDspDataReadFnc)
            {
                ret = E_NOT_OK;
            }
            else if ((USE_DATA_SYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                    || (USE_DATA_SYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort))
            {
                ret = pDspDidData->DcmDspDataReadFnc(
                        DCM_INVALID_UINT8,
                        &Data[DidSignalPos],
                        NULL_PTR);
            }
            else if ((USE_DATA_ASYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                    || (USE_DATA_ASYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort))
            {
                ret = pDspDidData->DcmDspDataReadFnc(
                        DCM_INITIAL,
                        &Data[DidSignalPos],
                        NULL_PTR);
            }
            else if ((USE_DATA_ASYNCH_FNC_ERROR == pDspDidData->DcmDspDataUsePort)
                    || (USE_DATA_ASYNCH_CLIENT_SERVER_ERROR == pDspDidData->DcmDspDataUsePort))
            {
                ret = pDspDidData->DcmDspDataReadFnc(
                        DCM_INITIAL,
                        &Data[DidSignalPos],
                        &ErrorCode);
            }
            else
            {
            }
            /*ResOffset equal to last position add last size of the signal of did*/
            DidSignalPos += Size;
        }
    }
    return ret;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"

#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x2A_DDDid_Read_Data(
        Dcm_OpStatusType OpStatus,
        uint16     RecDid,
        P2VAR(uint8, AUTOMATIC, AUTOMATIC)Data)
{
    uint8 DidSignalIndex;
    uint8 DidSignalNum;
    P2CONST(Dcm_DspDataType,TYPEDEF,DCM_CONST) pDspDidData;
    Std_ReturnType ret;
    P2VAR(Dcm_DDDidElementsDataTypes,TYPEDEF,DCM_CONST) DDDid;
    uint8 DDDidNum;
    uint8 iloop;
    uint8 DDDidIndex;
    uint8 IdInfoIndex;
    uint8 RangeInfoIndex;
    uint8 NewData[8] = {0};
    P2CONST(Dcm_DspReadMemoryRangeInfoType, AUTOMATIC, DCM_VAR_NOINIT)
     pDcmDspReadMemoryRangeInfo;
    P2CONST(Dcm_DspMemoryIdInfoType, AUTOMATIC, DCM_VAR_NOINIT)
     pDcmDspMemoryIdInfo;
    uint8 MemoryIdentifier;
    uint16 Did;
    uint8  Pos;
    uint8     Index;
    uint16 pDidCfgIndex;
    uint16 DidSignalPos = 0;
    uint16 Size;
    boolean Find = FALSE;
    Dcm_NegativeResponseCodeType ErrorCode;
    uint16 Offest = 0;

    for (iloop = 0; (iloop < DCM_DSP_DDDID_MAX_NUMBER) && (Find == FALSE); iloop++)
    {
        if (RecDid == Dcm_DDDid[iloop].DDDid)
        {
            Find = TRUE;
            DDDidIndex = iloop;
        }
    }
    if (Find == TRUE)
    {
        DDDidNum = Dcm_DDDid[DDDidIndex].DDDIDNumOfElements;
        DDDid = Dcm_DDDid[DDDidIndex].DcmDspAlternativeArgumentData;
        for (iloop = 0; iloop < DDDidNum; iloop++)
        {
            if (DDDid->Subfunction == DCM_UDS0X2C_01_DDBYDID)
            {
                Did = (uint16)(DDDid->Data & 0xFFFFUL);
                Pos = (uint8)((DDDid->Data & 0xFF0000UL) >> 16u);
                for (Index = 0;
                        Index < Dcm_DspCfg.DcmDspDidNum;
                        Index++)
                {
                    /*single did check*/
                    if ((Did == Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidId)
                    &&(TRUE == Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidUsed))
                    {
                        pDidCfgIndex = Index;
                        break;
                    }
                }

                DidSignalNum = Dcm_DspCfg.pDcmDspDid[pDidCfgIndex].DcmDspDidSignalNum;
                for (DidSignalIndex = 0;
                        DidSignalIndex < DidSignalNum;
                        DidSignalIndex ++)
                {
                    pDspDidData = Dcm_DspCfg.pDcmDspDid[pDidCfgIndex].
                            pDcmDspDidSignal[DidSignalIndex].pDcmDspDidData;
                    if (DCM_UINT8_DYN == pDspDidData->DcmDspDataType)
                    {
                        /*DidDataSize is dynamic*/
                        if (NULL_PTR == pDspDidData->DcmDspDataReadDataLengthFnc)
                        {
                            ret = E_NOT_OK;
                        }
                        else if((USE_DATA_SYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                                || (USE_DATA_SYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort))
                        {
                            ret = pDspDidData->DcmDspDataReadDataLengthFnc(
                                    DCM_INVALID_UINT8,
                                    &Size);
                        }
                        else if((USE_DATA_ASYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                                || (USE_DATA_ASYNCH_FNC_ERROR == pDspDidData->DcmDspDataUsePort)
                                || (USE_DATA_ASYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort)
                                || (USE_DATA_ASYNCH_CLIENT_SERVER_ERROR == pDspDidData->DcmDspDataUsePort))
                        {
                            ret = pDspDidData->DcmDspDataReadDataLengthFnc(OpStatus, &Size);
                        }
                        else
                        {}
                    }
                    else
                    {
                        /*DidDataSize is fixed*/
                        Size = ((pDspDidData->DcmDspDataSize + 7u) >> 3u);
                    }

                    DidSignalPos +=
                            ((Dcm_DspCfg.pDcmDspDid[pDidCfgIndex].
                               pDcmDspDidSignal[DidSignalIndex].DcmDspDidDataPos + 7u) >> 3u);
                    if (NULL_PTR == pDspDidData->DcmDspDataReadFnc)
                    {
                        ret = E_NOT_OK;
                    }
                    else if ((USE_DATA_SYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                            || (USE_DATA_SYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort))
                    {
                        ret = pDspDidData->DcmDspDataReadFnc(
                                DCM_INVALID_UINT8,
                                &NewData[DidSignalPos],
                                NULL_PTR);
                    }
                    else if ((USE_DATA_ASYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                            || (USE_DATA_ASYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort))
                    {
                        ret = pDspDidData->DcmDspDataReadFnc(
                                OpStatus,
                                &NewData[DidSignalPos],
                                NULL_PTR);
                    }
                    else if ((USE_DATA_ASYNCH_FNC_ERROR == pDspDidData->DcmDspDataUsePort)
                            || (USE_DATA_ASYNCH_CLIENT_SERVER_ERROR == pDspDidData->DcmDspDataUsePort))
                    {
                        ret = pDspDidData->DcmDspDataReadFnc(
                                OpStatus,
                                &NewData[DidSignalPos],
                                &ErrorCode);
                    }
                    else
                    {
                    }

                    if(E_NOT_OK == ret)
                    {
                        return E_NOT_OK;
                    }
                    DidSignalPos += Size;
                }
                Dcm_MemoryCopy(
                        &(NewData[Pos]),
                        &(Data[Offest]),
                        DDDid->Size);
                Offest += DDDid->Size;
            }
            else if (DDDid->Subfunction == DCM_UDS0X2C_02_DDBYMEMORY)
            {
                for(IdInfoIndex = 0u;
                        IdInfoIndex < Dcm_DspCfg.pDcmDspMemory->DcmDspMemoryIdInfoNum;
                        IdInfoIndex++)
                {
                    pDcmDspMemoryIdInfo =
                          &(Dcm_DspCfg.pDcmDspMemory->DcmDspMemoryIdInfo[IdInfoIndex]);
                    if (pDcmDspMemoryIdInfo != NULL_PTR)
                    {
                        for(RangeInfoIndex = 0;
                             RangeInfoIndex < pDcmDspMemoryIdInfo->DcmDspReadMemoryRangeInfoNum;
                             RangeInfoIndex++)
                        {
                            pDcmDspReadMemoryRangeInfo =
                                  &(pDcmDspMemoryIdInfo->DcmDspReadMemoryRangeInfo[RangeInfoIndex]);
                            if (pDcmDspReadMemoryRangeInfo != NULL_PTR)
                            {
                                if ((pDcmDspReadMemoryRangeInfo->DcmDspReadMemoryRangeLow
                                        <= DDDid->Data)
                                    && (pDcmDspReadMemoryRangeInfo->DcmDspReadMemoryRangeHigh
                                            >= (DDDid->Data + DDDid->Size - 1u)))
                                {
                                    MemoryIdentifier = Dcm_DspCfg.pDcmDspMemory->
                                            DcmDspMemoryIdInfo[IdInfoIndex].DcmDspMemoryIdValue;
                                }
                            }
                        }
                    }
                }

                ret = Dcm_ReadMemory(OpStatus,
                                        MemoryIdentifier,
                                        DDDid->Data,
                                        DDDid->Size,
                                        Data,
                                        &ErrorCode);
                if (DCM_READ_FAILED == ret)
                {
                    return E_NOT_OK;
                }
                else if(DCM_READ_FORCE_RCRRP == ret)
                {
                    return DCM_E_PENDING;
                }
                else if (DCM_READ_PENDING == ret)
                {
                    return DCM_E_PENDING;
                }
                else
                {
                    /*idle*/
                }
            }
            else
            {
                ret = E_NOT_OK;
            }
            DDDid++;
        }
    }
    else
    {
        ret = E_NOT_OK;
    }
    return ret;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"

/************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x2A_DDDidSessionCheck(
        uint8  DidInfoCfgIndex,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc)
{
    uint8   Index;
    boolean Flag = FALSE;
    P2CONST(Dcm_DspDidReadType, AUTOMATIC, DCM_APPL_CONST) pDspDidRead;
    Std_ReturnType   ret = E_OK;

    /***************************************
     * pDcmDspDidRead is NULL_PTR
     ***************************************/
    pDspDidRead  = Dcm_DspCfg.pDcmDspDidInfo[DidInfoCfgIndex].pDcmDspDidRead;
    if (NULL_PTR == pDspDidRead)
    {
        /*Dcm433:if the DcmDspDidRead of required Did is not configured,send NRC 0x31*/
        (*pNrc) = DCM_E_REQUESTOUTOFRANGE;
        ret = E_NOT_OK;
    }
    else
    {
        if (pDspDidRead->DcmDspDidReadSessionRefNum != 0u)
        {
            for (Index = 0;
                    (Index < (pDspDidRead->DcmDspDidReadSessionRefNum))
                            && (FALSE == Flag);
                    Index++)
            {
                if (Dcm_MkCtrl.Dcm_ActiveSes
                        == pDspDidRead->pDcmDspDidReadSessionRow[Index])
                {
                    Flag = TRUE;
                }
            }
            if (FALSE == Flag)
            {
                /*Dcm435:the reading processing is not supported
                 * in current security level,send NRC 0x7F*/
               (*pNrc) = DCM_E_SERVICENOTSUPPORTEDINACTIVESESSION;
                ret = E_NOT_OK;
            }
        }
        else
        {
            ret = E_OK;
        }
    }
    return(ret);
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif



/***************************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x2A_DidSecurityCheck(
        uint8  DidInfoCfgIndex,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc)
{
    P2CONST(Dcm_DspDidReadType, AUTOMATIC, DCM_APPL_CONST) pDspDidRead;
    uint8    SecNum;
    uint8    Index;
    Std_ReturnType   ret = E_OK;
    boolean  Flag = FALSE;

    /***************************************
     * pDcmDspDidRead is NULL_PTR
     ***************************************/
    pDspDidRead  = Dcm_DspCfg.pDcmDspDidInfo[DidInfoCfgIndex].pDcmDspDidRead;
    if (NULL_PTR == pDspDidRead)
    {
        ret = E_NOT_OK;
    }
    else
    {
        SecNum = pDspDidRead->DcmDspDidReadSecurityLevelRefNum;
        if (SecNum != 0u)
        {
            for (Index = 0; (Index < SecNum) && (FALSE == Flag); Index++)
            {
                if (Dcm_MkCtrl.Dcm_ActiveSec
                        == pDspDidRead->pDcmDspDidReadSecurityLevelRow[Index])
                {
                    Flag = TRUE;
                }
            }
            if (FALSE == Flag)
            {
                /*Dcm435:the reading processing is not supported in current security level,send NRC 0x33*/
               (*pNrc) = DCM_E_SECURITYACCESSDENIED;
                ret = E_NOT_OK;
            }
        }
        else
        {
            ret = E_OK;
        }
    }
    return(ret);
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif

/***************************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x2A_DDDidSecurityCheck(
        uint8  DidInfoCfgIndex,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc)
{
    P2CONST(Dcm_DspDidReadType, AUTOMATIC, DCM_APPL_CONST) pDspDidRead;
    uint8    SecNum;
    uint8    Index;
    Std_ReturnType   ret = E_OK;
    boolean  Flag = FALSE;

    /***************************************
     * pDcmDspDidRead is NULL_PTR
     ***************************************/
    pDspDidRead  = Dcm_DspCfg.pDcmDspDidInfo[DidInfoCfgIndex].pDcmDspDidRead;
    if (NULL_PTR == pDspDidRead)
    {
        /*Dcm433:if the DcmDspDidRead of required Did is not configured,send NRC 0x31*/
        (*pNrc) = DCM_E_REQUESTOUTOFRANGE;
        ret = E_NOT_OK;
    }
    else
    {
        SecNum = pDspDidRead->DcmDspDidReadSecurityLevelRefNum;
        if (SecNum != 0u)
        {
            for (Index = 0; (Index < SecNum) && (FALSE == Flag); Index++)
            {
                if (Dcm_MkCtrl.Dcm_ActiveSec
                        == pDspDidRead->pDcmDspDidReadSecurityLevelRow[Index])
                {
                    Flag = TRUE;
                }
            }
            if (FALSE == Flag)
            {
                /*Dcm435:the reading processing is not
                 * supported in current security level,send NRC 0x33*/
               (*pNrc) = DCM_E_SECURITYACCESSDENIED;
                ret = E_NOT_OK;
            }
        }
        else
        {
            ret = E_OK;
        }
    }
    return(ret);
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif

/************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x2A_DidSessionCheck(
        uint8  DidInfoCfgIndex)
{
    uint8   Index;
    boolean Flag = FALSE;
    P2CONST(Dcm_DspDidReadType, AUTOMATIC, DCM_APPL_CONST) pDspDidRead;
    Std_ReturnType   ret = E_OK;

    /***************************************
     * pDcmDspDidRead is NULL_PTR
     ***************************************/
    pDspDidRead  = Dcm_DspCfg.pDcmDspDidInfo[DidInfoCfgIndex].pDcmDspDidRead;
    if (NULL_PTR == pDspDidRead)
    {
        ret = E_NOT_OK;
    }
    else
    {
        if (pDspDidRead->DcmDspDidReadSessionRefNum != 0u)
        {
            for (Index = 0;
                    (Index < (pDspDidRead->DcmDspDidReadSessionRefNum))
                            && (FALSE == Flag);
                    Index++)
            {
                if (Dcm_MkCtrl.Dcm_ActiveSes
                        == pDspDidRead->pDcmDspDidReadSessionRow[Index])
                {
                    Flag = TRUE;
                }
            }
            if (FALSE == Flag)
            {
                ret = E_NOT_OK;
            }
        }
    }
    return(ret);
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif

#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)DspInternalUDS0x2A_DDDIDcheckPerSourceDID(
        uint16 DDDidIdx,
        P2VAR(Dcm_NegativeResponseCodeType, AUTOMATIC, AUTOMATIC)pNrc)
{
    Std_ReturnType  ret = E_OK;
    P2VAR(Dcm_DDDidElementsDataTypes,TYPEDEF,DCM_CONST) DDDid;
    uint8 DDDidNum;
    uint8 iloop;
    uint16 Did;
    uint8     RangeDidCfgIndex = 0;
    uint16     DidCfgIndex;
    boolean   RangeDidFlag;
    uint8     DidInfoCfgIndex;
    uint8 IdInfoIndex;
    P2CONST(Dcm_DspReadMemoryRangeInfoType, AUTOMATIC, DCM_VAR_NOINIT)
     pDcmDspReadMemoryRangeInfo;
    P2CONST(Dcm_DspMemoryIdInfoType, AUTOMATIC, DCM_VAR_NOINIT)
     pDcmDspMemoryIdInfo;
    uint8 RangeInfoIndex;
    uint8 index;
    uint8 SecNum;

    /* SWS_Dcm_01097 */
    if (Dcm_DspCfg.DcmDspDDDIDcheckPerSourceDID != NULL_PTR)
    {
        if (TRUE == (*Dcm_DspCfg.DcmDspDDDIDcheckPerSourceDID))
        {
            DDDidNum = Dcm_DDDid[DDDidIdx].DDDIDNumOfElements;
            DDDid = Dcm_DDDid[DDDidIdx].DcmDspAlternativeArgumentData;
            for (iloop = 0; (iloop < DDDidNum) && (E_NOT_OK != ret); iloop++)
            {
                if (DDDid->Subfunction == DCM_UDS0X2C_01_DDBYDID)
                {
                    Did = (uint16)(DDDid->Data & 0xFFFFUL);
                    ret = DspInternalUDS0x2A_DDDidCheck(DCM_INITIAL,
                                                Did,
                                                &RangeDidCfgIndex,
                                                &DidCfgIndex,
                                                &RangeDidFlag);
                    if (E_OK == ret)
                    {
                        if (TRUE == RangeDidFlag)
                        {
                            DidInfoCfgIndex = Dcm_DspCfg.pDcmDspDidRange[RangeDidCfgIndex].
                                    DcmDspDidRangeInfoIndex;
                        }
                        else
                        {
                            DidInfoCfgIndex = Dcm_DspCfg.pDcmDspDid[DidCfgIndex].
                                    DcmDspDidInfoIndex;
                        }

                        /*SWS_Dcm_00433,SWS_Dcm_00434,SWS_Dcm_00435*/
                        /*check the current session*/
                        #if(STD_ON == DCM_SESSION_FUNC_ENABLED)
                        ret = DspInternalUDS0x2A_DDDidSessionCheck(
                                DidInfoCfgIndex,
                                pNrc);
                        if(E_NOT_OK == ret)
                        {
                            return  E_NOT_OK;
                        }
                        #endif

                        /***************************************/
                        /*check the current security level*/
                        #if(STD_ON == DCM_SECURITY_FUNC_ENABLED)
                        ret = DspInternalUDS0x2A_DDDidSecurityCheck(
                                DidInfoCfgIndex,
                                pNrc);
                        if(E_NOT_OK == ret)
                        {
                            return  E_NOT_OK;
                        }
                        #endif
                    }
                }
                else if (DDDid->Subfunction == DCM_UDS0X2C_02_DDBYMEMORY)
                {
                    ret = E_NOT_OK;
                    for(IdInfoIndex = 0u;
                          IdInfoIndex < Dcm_DspCfg.pDcmDspMemory->DcmDspMemoryIdInfoNum;
                          IdInfoIndex++)
                    {
                        pDcmDspMemoryIdInfo = &(Dcm_DspCfg.pDcmDspMemory->
                                DcmDspMemoryIdInfo[IdInfoIndex]);
                        if (pDcmDspMemoryIdInfo != NULL_PTR)
                        {
                            for(RangeInfoIndex = 0;
                                 RangeInfoIndex < pDcmDspMemoryIdInfo->DcmDspReadMemoryRangeInfoNum;
                                 RangeInfoIndex++)
                            {
                                pDcmDspReadMemoryRangeInfo =
                                    &(pDcmDspMemoryIdInfo->DcmDspReadMemoryRangeInfo[RangeInfoIndex]);
                                SecNum = pDcmDspReadMemoryRangeInfo->DcmDspReadMemorySecurityLevelRefNum;
                                if (SecNum != 0u)
                                {
                                    for (index = 0; (index < SecNum); index++)
                                    {
                                        if (Dcm_MkCtrl.Dcm_ActiveSec
                                             == pDcmDspReadMemoryRangeInfo->
                                             pDcmDspReadMemorySecurityLevelRow[index])
                                        {
                                            ret = E_OK;
                                        }
                                    }
                                }
                                else
                                {
                                     ret = E_OK;
                                }
                            }
                        }
                    }
                    if (ret == E_NOT_OK)
                    {
                        (*pNrc) = DCM_E_REQUESTOUTOFRANGE;
                    }
                }
                else
                {}
            }
        }
    }
    return ret;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif

/***************************/
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static Std_ReturnType  DspInternalUDS0x2A_DidCheck(
        uint16 RecDid,
        P2VAR(uint8, AUTOMATIC, AUTOMATIC)pDidCfgIndex,
        P2VAR(boolean, AUTOMATIC, AUTOMATIC)DDDid,
        P2VAR(uint8, AUTOMATIC, AUTOMATIC)DDDidIndex)
{
    uint8     Index;
    uint8     iloop;
    boolean   Flag = FALSE;
    Std_ReturnType  ret = E_NOT_OK;

    if ((RecDid >= 0xF200u) && (RecDid <= 0xF2FFu))
    {
        /*find the corresponding DID in configuration*/
        for (Index = 0; (Index < Dcm_DspCfg.DcmDspDidNum) && (FALSE == Flag); Index++)
        {
            /*single did check[SWS_Dcm_01096]*/
            if ((RecDid == Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidId)
                    && (TRUE == Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidUsed))
            {
                if ((Dcm_DspCfg.pDcmDspDidInfo[Dcm_DspCfg.pDcmDspDid[Index].
                                DcmDspDidInfoIndex].DcmDspDidDynamicallyDefined == TRUE)
                        && (Dcm_DspCfg.pDcmDspDidInfo[Dcm_DspCfg.pDcmDspDid[Index].
                                         DcmDspDidInfoIndex].DcmDspDDDIDMaxElements > 0u))
                {
                    for (iloop = 0;
                            (iloop < DCM_DSP_DDDID_MAX_NUMBER) && (Flag == FALSE);
                            iloop++)
                    {
                        if (RecDid == Dcm_DDDid[iloop].DDDid)
                        {
                            *DDDid = TRUE;
                            Flag = TRUE;
                            *DDDidIndex = iloop;
                            (*pDidCfgIndex) = Index;
                            ret = E_OK;
                        }
                    }
                }
                else
                {
                    Flag = TRUE;
                    (*pDidCfgIndex) = Index;
                    ret = E_OK;
                }
            }
        }
    }

    return(ret);
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif


/***************************/
#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(Std_ReturnType, DCM_CODE)Dcm_Uds0x2AServiceConditionCheck(
        uint8 ProtocolCtrlId,
        P2VAR(uint8, AUTOMATIC, AUTOMATIC)MsgCtrlId)
{
    Std_ReturnType ret;

    /*************************************************/
    /*if the required protocol is configured,get the index of runtime datum*/
    *MsgCtrlId = Dcm_ProtocolCtrl[ProtocolCtrlId].MsgCtrlIndex;

    /*************************************************/
    #if(STD_ON == DCM_SESSION_FUNC_ENABLED)
    /*session check,check whether the current
     *  session supports the request service*/
    ret = DsdInternal_SesCheck(ProtocolCtrlId,
            SID_READ_DATA_BY_PERIODIC_IDENTIFER);
    if(E_NOT_OK == ret)
    {
        /****@req DCM-FUNR-073[DCM211]****/
        /*the current session does not support
         *  the request service,send NRC = 0x7F*/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,
                DCM_E_SERVICENOTSUPPORTEDINACTIVESESSION);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return E_NOT_OK;
    }
    #endif

    /*************************************************/
    #if(STD_ON == DCM_SECURITY_FUNC_ENABLED)
    /*security check,check whether the current
     *  security supports the request service*/
    ret = DsdInternal_SecurityCheck(ProtocolCtrlId,
            SID_READ_DATA_BY_PERIODIC_IDENTIFER);
    if (E_NOT_OK == ret)
    {
        /****@req DCM-FUNR-074[DCM217]****/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,
                DCM_E_SECURITYACCESSDENIED); /*NRC = 0x33*/
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return E_NOT_OK;
    }
    #endif

    return E_OK;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"

#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(void, DCM_CODE)DspInternalUDS0x2A_Clear_SchedulerQueue(uint16 Index)
{
    SchedulerQueue[Index].Did = 0;
    SchedulerQueue[Index].Counter = 0;
    SchedulerQueue[Index].SubFunction = 0;
    SchedulerQueue[Index].Length = 0;
    SchedulerQueue[Index].ProtocolCtrlId = 0xFF;
    SchedulerQueue[Index].Data[0] = 0;
    SchedulerQueue[Index].Data[1] = 0;
    SchedulerQueue[Index].Data[2] = 0;
    SchedulerQueue[Index].Data[3] = 0;
    SchedulerQueue[Index].Data[4] = 0;
    SchedulerQueue[Index].Data[5] = 0;
    SchedulerQueue[Index].Data[6] = 0;
    SchedulerQueue[Index].Data[7] = 0;/* SWS_Dcm_01117 */
    SchedulerQueue[Index].DDDid = FALSE;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"

#define  DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
static FUNC(void, DCM_CODE)DspInternalUDS0x2A_Move_SchedulerQueue(uint16 Index)
{
    uint16 Cnt;
    for (Cnt = Index; Cnt < (SchedulerNum - 1u);Cnt++)
    {
        SchedulerQueue[Cnt].Did = SchedulerQueue[Cnt+1u].Did;
        SchedulerQueue[Cnt].Counter = SchedulerQueue[Cnt+1u].Counter;
        SchedulerQueue[Cnt].SubFunction = SchedulerQueue[Cnt+1u].SubFunction;
        SchedulerQueue[Cnt].Length = SchedulerQueue[Cnt+1u].Length;
        SchedulerQueue[Cnt].ProtocolCtrlId = SchedulerQueue[Cnt+1u].ProtocolCtrlId;
        SchedulerQueue[Cnt].DDDid = SchedulerQueue[Cnt+1u].DDDid;
    }
    DspInternalUDS0x2A_Clear_SchedulerQueue(Cnt);
    if (SchedulerIndex >= Index)
    {
        SchedulerIndex--;
    }
    SchedulerNum -= 1u;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"

#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
FUNC(void, DCM_CODE)  Dcm_UDS0x2ACheckNewSecurity(void)
{
    boolean SecSupport;
    boolean DDDidSupport = TRUE;
    uint16 Index;
    uint16 iloop;
    uint8     DidInfoCfgIndex;
    uint8   Idx;
    P2CONST(Dcm_DspDidReadType, AUTOMATIC, DCM_APPL_CONST) pDspDidRead;
#if(STD_ON == DCM_UDS_SERVICE0X2C_ENABLED)
    Dcm_NegativeResponseCodeType ErrorCode;
#endif

    /* SWS_Dcm_01110 */
    for(Index=0;Index<SchedulerNum;Index++)
    {
        SecSupport = FALSE;
        for (iloop = 0; iloop < Dcm_DspCfg.DcmDspDidNum; iloop++)
        {
            if ((SchedulerQueue[Index].Did == Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidId)
                &&(TRUE == Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidUsed))
            {
                DidInfoCfgIndex = Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidInfoIndex;
                pDspDidRead  = Dcm_DspCfg.pDcmDspDidInfo[DidInfoCfgIndex].pDcmDspDidRead;
                if (NULL_PTR != pDspDidRead)
                {
                    if (pDspDidRead->DcmDspDidReadSecurityLevelRefNum != 0u)
                    {
                        for (Idx = 0; (Idx < pDspDidRead->DcmDspDidReadSecurityLevelRefNum)
                        && (FALSE == SecSupport); Idx++)
                        {
                            if (Dcm_MkCtrl.Dcm_ActiveSec
                                    == pDspDidRead->pDcmDspDidReadSecurityLevelRow[Idx])
                            {
                                SecSupport = TRUE;
                            }
                        }
                    }
                    else
                    {
                        SecSupport = TRUE;
                    }
                    /* SWS_Dcm_01112 */
#if(STD_ON == DCM_UDS_SERVICE0X2C_ENABLED)
                    if ((SchedulerQueue[Index].DDDid == TRUE)
                            && (Dcm_DspCfg.DcmDspDDDIDcheckPerSourceDID != NULL_PTR)
                            && (TRUE == (*(Dcm_DspCfg.DcmDspDDDIDcheckPerSourceDID))))
                    {
                        for (Idx = 0; (Idx < DCM_DSP_DDDID_MAX_NUMBER); Idx++)
                        {
                            if (SchedulerQueue[Index].Did == Dcm_DDDid[Idx].DDDid)
                            {
                                if(E_NOT_OK ==
                                    DspInternalUDS0x2A_DDDIDcheckPerSourceDID(Idx,&ErrorCode))
                                {
                                    DDDidSupport = FALSE;
                                }
                            }
                        }
                    }
#endif
                }
            }
        }

        if ((SecSupport == FALSE) || (DDDidSupport == FALSE))
        {
            DspInternalUDS0x2A_Clear_SchedulerQueue(Index);
            DspInternalUDS0x2A_Move_SchedulerQueue(Index);
            Index--;
        }
    }
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"

#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
FUNC(void, DCM_CODE)  Dcm_UDS0x2ACheckNewSession(Dcm_SesCtrlType NewSes)
{
    boolean SesSupport;
    boolean SecSupport;
    boolean DDDidSupport = TRUE;
    uint16 Index;
    uint16 iloop;
    uint8     DidInfoCfgIndex;
    uint8   Idx;
    P2CONST(Dcm_DspDidReadType, AUTOMATIC, DCM_APPL_CONST) pDspDidRead;
#if(STD_ON == DCM_UDS_SERVICE0X2C_ENABLED)
    Dcm_NegativeResponseCodeType ErrorCode;
#endif

    /* SWS_Dcm_01107 */
    if (DCM_DEFAULT_SESSION == NewSes)
    {
        for(Index=0;Index<SchedulerNum;Index++)
        {
            if ((SchedulerPengingDid == SchedulerQueue[Index].Did)
                && (SchedulerPengingDDDid == TRUE))
            {
                /*[SWS_Dcm_01116],[SWS_Dcm_01115]*/
                (void)DspInternalUDS0x2A_DDDid_Read_Data(
                        DCM_CANCEL,
                        SchedulerQueue[Index].Did,
                        &(SchedulerQueue[Index].Data[1]));
                SchedulerPengingDid = 0;
                SchedulerPengingDDDid = FALSE;
            }
            DspInternalUDS0x2A_Clear_SchedulerQueue(Index);
        }
    }
    else
    {
        /* SWS_Dcm_01108   SWS_Dcm_01109 */
        for(Index=0;Index<SchedulerNum;Index++)
        {
            SesSupport = FALSE;
            SecSupport = FALSE;
            for (iloop = 0; iloop < Dcm_DspCfg.DcmDspDidNum; iloop++)
            {
                if ((SchedulerQueue[Index].Did == Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidId)
                    &&(TRUE == Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidUsed))
                {
                    DidInfoCfgIndex = Dcm_DspCfg.pDcmDspDid[Index].DcmDspDidInfoIndex;
                    pDspDidRead  = Dcm_DspCfg.pDcmDspDidInfo[DidInfoCfgIndex].pDcmDspDidRead;
                    if (NULL_PTR != pDspDidRead)
                    {
                        if (pDspDidRead->DcmDspDidReadSessionRefNum != 0u)
                        {
                            for (Idx = 0; (Idx < (pDspDidRead->DcmDspDidReadSessionRefNum))
                            && (FALSE == SesSupport); Idx++)
                            {
                                if (Dcm_MkCtrl.Dcm_ActiveSes == pDspDidRead->pDcmDspDidReadSessionRow[Idx])
                                {
                                    SesSupport = TRUE;
                                }
                            }
                        }
                        else
                        {
                            SesSupport = TRUE;
                        }
                        if (pDspDidRead->DcmDspDidReadSecurityLevelRefNum != 0u)
                        {
                            for (Idx = 0; (Idx < pDspDidRead->DcmDspDidReadSecurityLevelRefNum)
                            && (FALSE == SecSupport); Idx++)
                            {
                                if (Dcm_MkCtrl.Dcm_ActiveSec
                                        == pDspDidRead->pDcmDspDidReadSecurityLevelRow[Idx])
                                {
                                    SecSupport = TRUE;
                                }
                            }
                        }
                        else
                        {
                            SecSupport = TRUE;
                        }
                        /* SWS_Dcm_01111 */
#if(STD_ON == DCM_UDS_SERVICE0X2C_ENABLED)
                        if ((SchedulerQueue[Index].DDDid == TRUE)
                                && (Dcm_DspCfg.DcmDspDDDIDcheckPerSourceDID != NULL_PTR)
                                && (TRUE == (*(Dcm_DspCfg.DcmDspDDDIDcheckPerSourceDID))))
                        {
                            for (Idx = 0; (Idx < DCM_DSP_DDDID_MAX_NUMBER); Idx++)
                            {
                                if (SchedulerQueue[Index].Did == Dcm_DDDid[Idx].DDDid)
                                {
                                    if(E_NOT_OK
                                        == DspInternalUDS0x2A_DDDIDcheckPerSourceDID(
                                                Idx,
                                                &ErrorCode))
                                    {
                                        DDDidSupport = FALSE;
                                    }
                                }
                            }
                        }
#endif
                    }
                }
            }

            if ((SesSupport == FALSE) || (SecSupport == FALSE) || (DDDidSupport == FALSE))
            {
                if ((SchedulerPengingDid == SchedulerQueue[Index].Did)
                    && (SchedulerPengingDDDid == TRUE))
                {
                    /*[SWS_Dcm_01116],[SWS_Dcm_01115]*/
                    (void)DspInternalUDS0x2A_DDDid_Read_Data(
                            DCM_CANCEL,
                            SchedulerQueue[iloop].Did,
                            &(SchedulerQueue[iloop].Data[1]));
                    SchedulerPengingDid = 0;
                    SchedulerPengingDDDid = FALSE;
                }
                DspInternalUDS0x2A_Clear_SchedulerQueue(Index);
                DspInternalUDS0x2A_Move_SchedulerQueue(Index);
                Index--;
            }
        }
    }
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"

/***************************/
#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
FUNC(Std_ReturnType, DCM_CODE)Dcm_UDS0x2A(
        Dcm_OpStatusType OpStatus,
        uint8  ProtocolCtrlId,
        P2VAR(Dcm_NegativeResponseCodeType,AUTOMATIC,DCM_VAR) ErrorCode)
{
#if(STD_ON == DCM_DSP_DID_FUNC_ENABLED)
    uint16    RecDid;
    uint16    Offset;
    uint8     DidCfgIndex = 0;
    uint8     DidInfoCfgIndex;
    uint8     iloop;
    uint8     index;
    uint8     TxChannelCtrlIndex;
    uint8     TxChannelCfgIndex;
    uint8 DidNum;
    uint8 DidSessionSupportNum = 0;
    uint8 DidSupportNum = 0;
    uint8 DidSupportNumStored = 0;
    P2CONST(Dcm_DspDataType,TYPEDEF,DCM_CONST) pDspDidData;
    boolean DDDid = FALSE;
    uint8 DDDidIndex = 0;
    uint16 Size = 0;
#endif
    uint8     MsgCtrlId = 0;
    Std_ReturnType ret;
    uint8     Subfunction;
    boolean   Find = FALSE;
#if (DCM_DSP_MAX_PERIODIC_DID_TO_READ != 0xFFFFu)
    static VAR(DidRxQueueTypes, DCM_VAR_NOINIT) DidRxQueue[DCM_DSP_MAX_PERIODIC_DID_TO_READ];
#endif

    /*************************************************/
    ret = Dcm_Uds0x2AServiceConditionCheck(ProtocolCtrlId, &MsgCtrlId);
    if(E_OK != ret)
    {
        return ret;
    }

    Subfunction = Dcm_MsgCtrl[MsgCtrlId].MsgContext.pReqData[1u];

    /*check the massage length*/
    if ((Dcm_MsgCtrl[MsgCtrlId].MsgContext.ReqDataLen
            < DCM_UDS0X2A_SUBFUNC0X04_REQ_DATA_MINLENGTH)
        || ((Dcm_MsgCtrl[MsgCtrlId].MsgContext.ReqDataLen
                < DCM_UDS0X2A_REQ_DATA_MINLENGTH)
            && ((DCM_UDS0X2A_01_SLOW == Subfunction)
                    || (DCM_UDS0X2A_02_MEDIUM == Subfunction)
                    || (DCM_UDS0X2A_03_FAST == Subfunction)))
        || ((uint32)((uint32)Dcm_DspCfg.DcmDspMaxPeriodicDidToRead + 2u)
                < Dcm_MsgCtrl[MsgCtrlId].MsgContext.ReqDataLen))/* SWS_Dcm_00843 */
    {
        /*the length of massage is not correct,send NRC 0x13*/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,
                DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return E_NOT_OK;
    }

    /*check transmissionMode SWS_Dcm_01094 */
    if ((Subfunction < DCM_UDS0X2A_01_SLOW)
            || (Subfunction > DCM_UDS0X2A_04_STOP))
    {
        /*if transmissionMode not supported,send NRC 0x31*/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_REQUESTOUTOFRANGE);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return  E_NOT_OK;
    }

#if (STD_OFF == DCM_DSP_DID_FUNC_ENABLED)
    /*NRC 0x31:request out of range*/
    (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_REQUESTOUTOFRANGE);
    DsdInternal_ProcessingDone(ProtocolCtrlId);
    return E_NOT_OK;

#else
    DidNum = (uint8)(Dcm_MsgCtrl[MsgCtrlId].MsgContext.ReqDataLen - 2u);
#if (DCM_DSP_MAX_PERIODIC_DID_TO_READ != 0xFFFFu)
    /*Repetition of the same periodicDataIdentifier
     *  in a single request message is not
     * allowed and the server shall ignore them
     * all except one periodicDataIdentifer if
     * the client breaks this rule.*/
    for (iloop = 0;iloop < DCM_DSP_MAX_PERIODIC_DID_TO_READ;iloop++)
    {
        DidRxQueue[iloop].Did = 0;
        DidRxQueue[iloop].Length = 0;
        DidRxQueue[iloop].DDDid = FALSE;
    }
    for (iloop = 0;iloop < DidNum;iloop++)
    {
        for (index = 0;
                (index < DCM_DSP_MAX_PERIODIC_DID_TO_READ) && (Find == FALSE);
                index++)
        {
            if(DidRxQueue[index].Did
               == (uint16)((uint16)((uint16)(0xF2u) << 8u) |((uint16) Dcm_MsgCtrl[MsgCtrlId].MsgContext.pReqData[2u + iloop])))
            {
                Find = TRUE;
            }
            if (DidRxQueue[index].Did == 0u)
            {
                DidRxQueue[index].Did =
                        (uint16)((uint16)(0xF2u) << 8u)
                    |((uint16) Dcm_MsgCtrl[MsgCtrlId].MsgContext.pReqData[2u + iloop]);
                break;
            }
        }
        if (Find == TRUE)
        {
            /*send NRC 0x22*/
            (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_CONDITIONSNOTCORRECT);
            DsdInternal_ProcessingDone(ProtocolCtrlId);
            return  E_NOT_OK;
        }
    }
#endif
    for (iloop = 0;iloop < DCM_DSP_MAX_PERIODIC_DID_TO_READ;iloop++)
    {
        DidRxQueue[iloop].Did = 0;
        DidRxQueue[iloop].Length = 0;
        DidRxQueue[iloop].DDDid = FALSE;
    }
    switch(Subfunction)
    {
    case DCM_UDS0X2A_01_SLOW:
    case DCM_UDS0X2A_02_MEDIUM:
    case DCM_UDS0X2A_03_FAST:
        for (iloop = 0;iloop < DidNum;iloop++)
        {
            /*get the required DID from request message*/
            RecDid = (uint16)((uint16)(0xF2u) << 8u)
                    |((uint16) Dcm_MsgCtrl[MsgCtrlId].MsgContext.pReqData[2u + iloop]);
            if (E_OK == DspInternalUDS0x2A_DidCheck(
                    RecDid,
                    &DidCfgIndex,
                    &DDDid,
                    &DDDidIndex))/* SWS_Dcm_01095 */
            {
                DidInfoCfgIndex = Dcm_DspCfg.pDcmDspDid[DidCfgIndex].DcmDspDidInfoIndex;
                if (Dcm_DspCfg.pDcmDspDidInfo[DidInfoCfgIndex].pDcmDspDidRead != NULL_PTR)
                {
    #if(STD_ON == DCM_SESSION_FUNC_ENABLED)
                    ret = DspInternalUDS0x2A_DidSessionCheck(DidInfoCfgIndex);
    #endif
                    if(E_OK == ret)
                    {
                        DidSessionSupportNum++;
                        /***************************************/
                        /*check the current security level*/
                        #if(STD_ON == DCM_SECURITY_FUNC_ENABLED)
                        ret = DspInternalUDS0x2A_DidSecurityCheck(DidInfoCfgIndex,ErrorCode);
                        #endif
                        if((E_NOT_OK == ret) && (*ErrorCode == DCM_E_SECURITYACCESSDENIED))
                        {
                            /* SWS_Dcm_00722 */
                            (void)DsdInternal_SetNrc(ProtocolCtrlId,*ErrorCode);
                            DsdInternal_ProcessingDone(ProtocolCtrlId);
                            return  E_NOT_OK;
                        }
                        else if (E_OK == ret)
                        {
                            if ((DDDid == TRUE) && (*(Dcm_DspCfg.DcmDspDDDIDcheckPerSourceDID) == TRUE))
                            {
                                ret = DspInternalUDS0x2A_DDDIDcheckPerSourceDID(DDDidIndex,ErrorCode);
                                if (E_OK != ret)
                                {
                                    (void)DsdInternal_SetNrc(ProtocolCtrlId,*ErrorCode);
                                    DsdInternal_ProcessingDone(ProtocolCtrlId);
                                    return ret;
                                }
                            }
                            if (DDDid == TRUE)
                            {
                                DidRxQueue[DidSupportNum].Length = Dcm_DDDid[DDDidIndex]
                                                                             .DDDIDNumOfElements;
                                DidRxQueue[DidSupportNum].DDDid = TRUE;
                            }
                            else
                            {
                                /*call the ConditionCheckRead function*/
                                for (index = 0;
                                        index < Dcm_DspCfg.pDcmDspDid[DidCfgIndex].DcmDspDidSignalNum;
                                        index++)
                                {
                                    /* SWS_Dcm_01098 */
                                    pDspDidData = Dcm_DspCfg.pDcmDspDid[DidCfgIndex].
                                            pDcmDspDidSignal[index].pDcmDspDidData;
                                    if ((pDspDidData->DcmConditionCheckReadFncUsed == TRUE)
                                        && (pDspDidData->DcmDspDataConditionCheckReadFnc
                                                != NULL_PTR))
                                    {
                                        if (E_NOT_OK == pDspDidData->DcmDspDataConditionCheckReadFnc(
                                                OpStatus,
                                                ErrorCode))
                                        {
                                            (void)DsdInternal_SetNrc(ProtocolCtrlId,*ErrorCode);
                                            DsdInternal_ProcessingDone(ProtocolCtrlId);
                                            return ret;
                                        }
                                    }
                                    if (pDspDidData->DcmDspDataType == DCM_UINT8_DYN)
                                    {
                                        /*DidDataSize is dynamic*/
                                        if (NULL_PTR == pDspDidData->DcmDspDataReadDataLengthFnc)
                                        {
                                            /*DcmDspDidReadDataLengthFnc is NULL,send NRC 0x22*/
                                            (void)DsdInternal_SetNrc(ProtocolCtrlId,
                                                    DCM_E_CONDITIONSNOTCORRECT);
                                            DsdInternal_ProcessingDone(ProtocolCtrlId);
                                            return E_NOT_OK;
                                        }
                                        else if((USE_DATA_SYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                                                || (USE_DATA_SYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort))
                                        {
                                            ret = pDspDidData->DcmDspDataReadDataLengthFnc(DCM_INVALID_UINT8, &Size);
                                        }
                                        else if((USE_DATA_ASYNCH_FNC == pDspDidData->DcmDspDataUsePort)
                                                || (USE_DATA_ASYNCH_FNC_ERROR == pDspDidData->DcmDspDataUsePort)
                                                || (USE_DATA_ASYNCH_CLIENT_SERVER == pDspDidData->DcmDspDataUsePort)
                                                || (USE_DATA_ASYNCH_CLIENT_SERVER_ERROR == pDspDidData->DcmDspDataUsePort))
                                        {
                                            ret = pDspDidData->DcmDspDataReadDataLengthFnc(OpStatus, &Size);
                                        }
                                        else
                                        {}
                                        DidRxQueue[DidSupportNum].Length += Size;
                                    }
                                    else
                                    {
                                        DidRxQueue[DidSupportNum].Length = ((pDspDidData->DcmDspDataSize + 7u) >> 3u);
                                    }
                                }
                            }
                            if (DidRxQueue[DidSupportNum].Length > 7u)
                            {
                                /*can only transfer IF PDU*/
                                DidRxQueue[DidSupportNum].Length = 0;
                                DidRxQueue[DidSupportNum].DDDid = FALSE;
                            }
                            else
                            {
                                DidRxQueue[DidSupportNum].Did = RecDid;
                                DidSupportNum++;
                            }
                        }
                        else
                        {
                            /*idle*/
                        }
                    }
                }
            }
        }
        break;
    case DCM_UDS0X2A_04_STOP:
        if (DidNum == 0u)
        {
            for (iloop = 0;iloop < DCM_DSP_MAX_PERIODIC_DID_SCHEDULER;iloop++)
            {
                DspInternalUDS0x2A_Clear_SchedulerQueue(iloop);
            }
            SchedulerNum = 0;
            SchedulerIndex = 0;
        }
        else
        {
            for (iloop = 0;iloop < DidNum;iloop++)
            {
                RecDid = (uint16)(((uint16)0xF2) << 8u)|(Dcm_MsgCtrl[MsgCtrlId].MsgContext.pReqData[2u + iloop]);
                for (index = 0;index < SchedulerNum;index++)
                {
                    if (SchedulerQueue[index].Did == RecDid)
                    {
                        DspInternalUDS0x2A_Move_SchedulerQueue(index);
                    }
                }
            }
        }
        break;
    default:
        break;
    }

    if ((DidSessionSupportNum == 0u) && (DCM_UDS0X2A_04_STOP != Subfunction))
    {
        /*at least one DID is supported in the active session,not then send NRC 0x31*/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_REQUESTOUTOFRANGE);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return  E_NOT_OK;
    }

    if (DCM_UDS0X2A_04_STOP != Subfunction)
    {
        for (index = 0; index < DidSupportNum; index++)
        {
            Find = FALSE;
            for (iloop = 0;(iloop < DCM_DSP_MAX_PERIODIC_DID_SCHEDULER) && (Find == FALSE);iloop++)
            {
                if (SchedulerQueue[iloop].Did == DidRxQueue[index].Did)
                {
                    Find = TRUE;
                    DidSupportNumStored += 1u;
                }
            }
        }

        if ((SchedulerNum + DidSupportNum - DidSupportNumStored) > DCM_DSP_MAX_PERIODIC_DID_SCHEDULER)
        {
            /*scheduler free to store all supported pDIDs requested,not then send NRC 0x31*/
            (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_REQUESTOUTOFRANGE);
            DsdInternal_ProcessingDone(ProtocolCtrlId);
            return  E_NOT_OK;
        }
        /*SWS_Dcm_00851*/
        for (index = 0; index < DidSupportNum; index++)
        {
            Find = FALSE;
            for (iloop = 0;(iloop < DCM_DSP_MAX_PERIODIC_DID_SCHEDULER) && (Find == FALSE);iloop++)
            {
                if (SchedulerQueue[iloop].Did == DidRxQueue[index].Did)
                {
                    Find = TRUE;
                    SchedulerQueue[iloop].SubFunction = Subfunction;
                    SchedulerQueue[iloop].Length = DidRxQueue[index].Length + 1u;
                    SchedulerQueue[iloop].Counter = 0;
                    SchedulerQueue[iloop].ProtocolCtrlId = ProtocolCtrlId;
                    SchedulerQueue[iloop].DDDid = DidRxQueue[index].DDDid;
                }
            }
            if (Find == FALSE)
            {
                for (iloop = 0;(iloop < DCM_DSP_MAX_PERIODIC_DID_SCHEDULER) && (Find == FALSE);iloop++)
                {
                    if (SchedulerQueue[iloop].Did == 0u)
                    {
                        Find = TRUE;
                        SchedulerQueue[iloop].Did = DidRxQueue[index].Did;
                        SchedulerQueue[iloop].SubFunction = Subfunction;
                        SchedulerQueue[iloop].Length = DidRxQueue[index].Length + 1u;
                        SchedulerQueue[iloop].Counter = 0;
                        SchedulerQueue[iloop].ProtocolCtrlId = ProtocolCtrlId;
                        SchedulerQueue[iloop].DDDid = DidRxQueue[index].DDDid;
                        if (SchedulerIndexChanged == FALSE)
                        {
                            SchedulerIndexChanged = TRUE;
                            SchedulerIndex = iloop;
                        }
                        SchedulerNum += 1u;
                    }
                }
            }
        }
    }

    /*assemble and send positive response*/
    TxChannelCtrlIndex = Dcm_MsgCtrl[MsgCtrlId].Dcm_TxCtrlChannelIndex;
    TxChannelCfgIndex = Dcm_ChannelCtrl[TxChannelCtrlIndex].Dcm_ChannelCfgIndex;
    Offset = (Dcm_DslCfg.pDcmChannelCfg)[TxChannelCfgIndex].offset;

    /* check tx data length */
    if((1u) > (Dcm_DslCfg.pDcmChannelCfg[TxChannelCfgIndex].Dcm_DslBufferSize))
    {
        /*Pdu length is bigger than buffer size,ignore the request message */
        (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_RESPONSETOOLONG);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return E_NOT_OK;
    }
    SchedulerIndexChanged = FALSE;

    Dcm_Channel[Offset] = 0x6A;
    SchM_Enter_Dcm(Dcm_MsgCtrl);
    Dcm_MsgCtrl[MsgCtrlId].MsgContext.ResMaxDataLen = 1u;
    Dcm_MsgCtrl[MsgCtrlId].MsgContext.ResDataLen    = 1u;
    Dcm_MsgCtrl[MsgCtrlId].MsgContext.pResData      = &Dcm_Channel[Offset];
    SchM_Exit_Dcm(Dcm_MsgCtrl);
    DsdInternal_ProcessingDone(ProtocolCtrlId);
#endif
    return  E_OK;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif

